package com.jiubanqingchen.plugin.easyexcel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Model;
import com.jiubanqingchen.framework.consts.FileContentType;
import com.jiubanqingchen.kit.BlankKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * easy excel 支持类
 *
 * @author light_dust
 * @since 2020/12/26 17:42
 */
@SuppressWarnings({"rawtypes"})
public class EasyExcelSupport implements IEasyExcel {

    private static final Logger logger = LoggerFactory.getLogger(EasyExcelSupport.class);

    private List<List<String>> headList = null;

    private List<List<Object>> dataList = null;

    private ExcelWriterBuilder excelWriterBuilder = null;

    private List<WriteHandler> writeHandlerList = null;

    private List<Converter<?>> converterList = null;

    @Override
    public void download() {
        ExcelWriterSheetBuilder excelWriterSheetBuilder = this.excelWriterBuilder.head(headList).sheet();
        if (BlankKit.notBlankList(writeHandlerList)) {
            writeHandlerList.forEach(excelWriterSheetBuilder::registerWriteHandler);
        }
        if (BlankKit.notBlankList(converterList)) {
            converterList.forEach(excelWriterSheetBuilder::registerConverter);
        }
        excelWriterSheetBuilder.doWrite(dataList);
    }

    public EasyExcelSupport(HttpServletResponse response, String fileName) {
        try {
            setResponseHeader(response, fileName);
            excelWriterBuilder = EasyExcel.write(response.getOutputStream());
        } catch (IOException e) {
            logger.info("create excelWriterBuilder fail for outputStream!", e);
        }
    }

    public EasyExcelSupport(String pathName) {
        excelWriterBuilder = EasyExcel.write(pathName);
    }

    public EasyExcelSupport(File file) {
        excelWriterBuilder = EasyExcel.write(file);
    }

    public EasyExcelSupport addWriteHandler(WriteHandler writeHandler) {
        if (writeHandler != null) {
            if (writeHandlerList == null) writeHandlerList = new ArrayList<>();
            writeHandlerList.add(writeHandler);
        }
        return this;
    }

    public EasyExcelSupport addConverter(Converter converter) {
        if (converter != null) {
            if (converterList == null) converterList = new ArrayList<>();
            converterList.add(converter);
        }
        return this;
    }

    public EasyExcelSupport setModelList(List<? extends Model> modelList) {
        if (BlankKit.notBlankList(modelList)) {
            Set<String> keySet = CPI.getAttrs(modelList.get(0)).keySet();
            headList = new ArrayList<>();
            dataList = new ArrayList<>();
            for (String s : keySet) {
                List<String> headChild = new ArrayList<>();
                headChild.add(s);
                headList.add(headChild);
            }
            modelList.forEach(model -> dataList.add(Arrays.asList(model._getAttrValues())));
        }
        return this;
    }

    public EasyExcelSupport setModelList(List<? extends Model> modelList, Map<String, String> headMap) {
        if (headMap == null) return setModelList(modelList);
        headList = new ArrayList<>();

        Set<String> keySet = headMap.keySet();
        keySet.forEach(key -> {
            List<String> headChild = new ArrayList<>();
            headChild.add(headMap.get(key));
            this.headList.add(headChild);
        });

        if (BlankKit.notBlankList(modelList)) {
            dataList = new ArrayList<>();
            //获取dataList
            modelList.forEach(model -> {
                List<Object> dataChild = new ArrayList<>();
                keySet.forEach(key -> dataChild.add(model.get(key)));
                this.dataList.add(dataChild);
            });
        }
        return this;
    }

    public EasyExcelSupport setHeadList(List<List<String>> headList) {
        this.headList = headList;
        return this;
    }

    public EasyExcelSupport setDataList(List<List<Object>> dataList) {
        this.dataList = dataList;
        return this;
    }

    /**
     * 设置下载头
     *
     * @param response HttpServletResponse
     * @param fileName 文件名称
     */
    private void setResponseHeader(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        String encoding = "UTF-8";
        response.setContentType(FileContentType.EXCEL);
        response.setCharacterEncoding(encoding);
        String excelName = URLEncoder.encode(fileName + ".xlsx", encoding); // 这里URLEncoder.encode可以防止中文乱码
        response.setHeader("Content-disposition", "attachment;filename=" + excelName);
        response.setHeader("filename", excelName);
    }
}
